$.fn.city = function(config) {
    config = config || {};
    var defaultCode = config.code || 0;
    defaultCode = parseInt(defaultCode);
    var defaultStreetCode = 0;
    var fn = $(this);
    var callback = config.callback || function(){};
    var cityTitle = $('<div id="city-title" tabindex="0" class="city-title has-city-title"></div>');
    var overlay = $('<div class="ks-overlay"><div class="ks-overlay-content"><div class="city-select-warp"></div></div></div>');
    var tab = $('<div class="city-select-tab"><a class="current" attr-cont="city-province">省份</a><a class="" attr-cont="city-city" data-spm-anchor-id="0.0.0.0">城市</a><a class="" attr-cont="city-district">县区</a><a class="last" attr-cont="city-street">街道</a></div>');
    var selectContent = $('<div class="city-select-content"></div>');
    var warp = overlay.find('.city-select-warp');
    var province = $('<div class="city-select city-province"></div>');
    var city = $('<div class="city-select city-city"></div>');
    var district = $('<div class="city-select city-district"></div>');
    var street = $('<div class="city-select city-city-select city-street"></div>');
    var cityBox = [province,city,district,street];
    var allData = {};
    var provinceData = {};
    var cityData = {};
    var districtData = {};
    var streetData = {};
    var streetStore = {}
    var checkedBox = {
        0 : {},
        1 : {},
        2 : {},
        3 : {}
    };
    function init() {
        initStyle();
        getData(function(d){
            success(d);
        });
        bindEvent();
    }

    function bindEvent() {
        $('body').on('click', function(e) {
            var o = $(e.target);
            if (!o.parents('.lSelect').length) {
                overlay.hide();
            }
        });
        fn.on('click', function(e) {
            var t = $(e.target);
            if (t.is(cityTitle) || t.is(fn)) {
                overlay.show();
            }
        });
        for (var i in cityBox) {
            var obj = cityBox[i];
            obj.on('click', 'a', function() {
                var name = $(this).html();
                var code = parseInt($(this).attr('code'));
                callback(code, name);
                if (code % 1000000 == 0) {
                    var type = 0;
                } else if (code % 1000 == 0) {
                    var type = 1;
                } else if (code > 1000000000) {
                    var type = 3;
                } else {
                    var type = 2;
                }
                var data = getDataByCode(code, type);
                var html = getHtml(data);
                for (var i in checkedBox) {
                    if ($(this).attr('attr-id') == '-1') {
                        checkedBox[3] = {};
                        break;
                    }
                    if (i > type) {
                        checkedBox[i] = {};
                    } else if (type == i) {
                        checkedBox[i] = {name: name, code: code};
                    } else {
                        checkedBox[type] = {name: name, code: code};
                    }
                }
                cityTitle.html(function() {
                    var html = '';
                    var l = '';
                    for (var i in checkedBox) {
                        var data = checkedBox[i];
                        if (!data.name) {
                            break;
                        }
                        var name = data.name;
                        var code = data.code;
                        html += l + name;
                        l = ' <span style="color:#cfcfcf">/</span> ';
                    }
                    return html;
                });
                if (type != 2) {
                    if (isEmpty(data)) {
                        overlay.hide();
                        return;
                    }
                }
                if ($(this).attr('attr-id') == '-1') {
                    overlay.hide();
                    return;
                }
                if (type == 0) {
                    province.hide();
                    city.html(html).show();
                } else if(type == 1) {
                    city.hide();
                    district.html(html).show();
                } else if (type == 2) {
                    district.hide();
                    street.show();
                }
                if (type != 3) {
                    tab.find('a').removeClass('current').eq(type + 1).addClass('current');
                } else {
                    overlay.hide();
                }
            });
        }
        tab.find('a').on('click', function() {
            $(this).siblings().removeClass('current');
            $(this).addClass('current');
            var index = $(this).index();
            var box = [province, city, district, street];
            for (var i in box) {
                if (i == index) {
                    box[i].show();
                } else {
                    box[i].hide();
                }
            }
        });
    }

    function getDataByCode(code, type) {
        if (type == 0) {
            cityData = {};
            for (var i in allData) {
                var t = i % code;
                if (t && t < 1000000 && i % 1000 == 0) {
                    cityData[i] = allData[i];
                }
            }
            return cityData;
        } else if (type == 1){
            districtData = {};
            for (var i in allData) {
                var t = i % code;
                if (t && t < 100) {
                    districtData[i] = allData[i];
                }
            }
            return districtData;
        } else if (type == 2){
            streetData = {};
            if (streetStore[code]) {
                streetData = streetStore[code];
                appendStreetData(streetData, type, code);
            } else {
                $.ajax({
                    url: '/Ajax/City/getTowns',
                    data: {code: code},
                    dataType: 'json',
                    success: function(d) {
                        streetData = d.data;
                        streetStore[code] = streetData;
                        appendStreetData(streetData, type, code);
                    }
                });
            }
        }
        return {};
    }

    function appendStreetData(streetData, type, code) {
        var html = getHtml(streetData, type, code);
        street.html(html);
        if (defaultStreetCode) {
            street.find('a[code="' + defaultStreetCode + '"]').click();
            defaultStreetCode = 0;
        }
        if (isEmpty(streetData)) {
            overlay.hide();
        }
    }

    function isEmpty(data) {
        var is = true;
        for (var i in data) {
            is = false;
            break;
        }
        return is;
    }

    function success(d) {
        allData = d;
        for (var i in d) {
            if (i % 100000 == 0) {
                provinceData[i] = d[i];
            }
        }
        var provinceHtml = getHtml(provinceData);
        province.html(provinceHtml).show();
        if (defaultCode) {
            if (defaultCode > 10000000000) {
                var cc = defaultCode % 1000;
                defaultStreetCode = defaultCode;
                defaultCode = (defaultCode - cc) / 1000;
            }
            var s = [1000000, 1000, 0];
            for (var i in s) {
                var k = s[i];
                var y = k ? defaultCode % k : 0;
                var code = defaultCode -  y;
                selectContent.find('a[code="' + code + '"]').click();
            }
        }
    }

    function getHtml(d, type, code) {
        var html = '<dl class="fn-clear"><dd>';
        for (var i in d) {
            var name = d[i];
            html += '<a href="javascript:;" code="' + i + '">' + name + '</a>';
        }
        html += '</dd></dl>';
        if (type && !isEmpty(d) && type == 2) {
            html += '<dl class="fn-clear city-select-street border-top"><dd><a code="' + code + '" title="稍后再说" attr-id="-1" href="javascript:;">辖区</a><span style="color:#ccc"> </span></dd></dl>';
        }
        return html;
    }

    function getData(func) {
        $.ajax({
            url: '/Ajax/City/getCity',
            dataType: 'json',
            success: function (d) {
                func(d.data);
            }
        })
    }

    function initStyle() {
        fn.addClass('bf-select');
        fn.addClass('lSelect');
        fn.append(cityTitle);
        fn.append('<div class="bf-menu-button-dropdown"></div>');
        fn.append(overlay);
        warp.append(tab);
        warp.append(selectContent);
        selectContent.append(province);
        selectContent.append(city);
        selectContent.append(district);
        selectContent.append(street);
        overlay.hide();
        for (var i in cityBox) cityBox[i].hide();
    }
    init();
};